import datetime
from typing import Optional

from sqlalchemy import ForeignKey, String, func
from sqlalchemy.orm import Mapped, mapped_column, relationship

from src.application.server.enums import ServerPrivacy, ServerStatus, ServerType
from src.infrastructure.db.models.base import Base
from src.infrastructure.db.models.m2ms import server_categories


class Server(Base):
    __tablename__ = "server"
    __mapper_args__ = {"eager_defaults": True}

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[Optional[str]] = mapped_column(String(255))
    description: Mapped[Optional[str]] = mapped_column(String(255))
    status: Mapped[ServerStatus] = mapped_column(server_default="active")
    ip_address: Mapped[str] = mapped_column(String(100), nullable=False)
    inner_ip_address: Mapped[str] = mapped_column(String(100), nullable=False)
    apache_port: Mapped[str] = mapped_column(String(100), nullable=False)
    config_path: Mapped[str] = mapped_column(String(50), nullable=False)
    proxy_type: Mapped[ServerType] = mapped_column(nullable=False)
    proxy_privacy: Mapped[ServerPrivacy] = mapped_column(nullable=False)
    provider = relationship("ProxyProvider", back_populates="servers")
    provider_id: Mapped[int] = mapped_column(ForeignKey("provider.id"), nullable=False)
    ssh_port: Mapped[int] = mapped_column(nullable=False)
    categories = relationship("Category", secondary=server_categories, back_populates="servers")
    login: Mapped[str] = mapped_column(String(100), nullable=False)
    password: Mapped[str] = mapped_column(String(100), nullable=False)
    country = relationship("Country", back_populates="servers")
    country_id: Mapped[int] = mapped_column(ForeignKey("country.id"), nullable=False)
    proxies = relationship("Proxy", back_populates="server")
    was_added: Mapped[datetime.datetime] = mapped_column(server_default=func.now())

    def __str__(self):
        return self.ip_address

    def __repr__(self):
        return f"<Server №{self.id} {self.ip_address}>"
